package com.xcdh.learn.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Data
public class BaseEntity implements Serializable {
    /**
     * 拥有者
     */
    private Long owner = 1529122310080409602L;

    /**
     * 描述
     */
    @TableField("`desc`")
    private String desc;


    /**
     * 排序
     */
    @TableField("`sort`")
    private Integer sort;

    private String createTime ;


    public String[] columns(){
        Map<String, Object> map = mapWrapper(false , null);
        Set<String> strings = map.keySet();
        return strings.stream().map(f->String.format("`%s`" , f)).toArray(String[]::new);
    }



    public String[] columns(String ...filter){
        Map<String, Object> map = mapWrapper(false , filter);
        Set<String> strings = map.keySet();
        return strings.stream().map(f->String.format("`%s`" , f)).toArray(String[]::new);
    }

    public Map<String,Object> getUpdateMap(){
        return mapWrapper(false , null) ;
    }


    public Map<String,Object> mapWrapper(boolean isEmptyIgnore ,String[]filters){

        if(filters == null){
            filters = new String[0] ;
        }
        String reg = "[A-Z]" ;
        Pattern pattern = Pattern.compile(reg);
        List<String> allFieldValue = getAllFieldValue(this.getClass());
        Map<String,Object> map = new HashMap<>(allFieldValue.size()) ;
        for (int i = 0; i < allFieldValue.size(); i++) {
            String s = allFieldValue.get(i);
            String[] fv = s.split(":");
            String f = fv[0] ,v = fv.length == 1 ? "" : fv[1] ;
            Matcher matcher = pattern.matcher(f);
            String col = f ;
            while (matcher.find()){
                String t = matcher.group();
                col = col.replace(t,String.format("_%s",t.toLowerCase())) ;
            }
            if(isEmptyIgnore && (Objects.equals(v, "null") || StringUtils.isEmpty(v))){
            }else {
                if(!Arrays.asList(filters).contains(col)){
                    map.put(col , Objects.equals(v, "null") ? null : v) ;
                }

            }
        }
        return map ;
    }

    public Map<String,Object> mapWrapper(){
        return mapWrapper(false , null) ;
    }
    public Map<String,Object> mapWrapper(String ...filters){
        return mapWrapper(false , filters) ;
    }

    private List<String> getAllFieldValue(Class cls){
        List<String> fs = new ArrayList<>() ;
        Field[] fields = cls.getDeclaredFields();
        Class superclass = cls.getSuperclass();
        fs.addAll(getFieldsValue(fields)) ;
        if(!Objects.equals(superclass.getName() , "java.lang.Object")){
            fs.addAll(getAllFieldValue(superclass)) ;
        }
        return fs ;
    }

    private List<String> getFieldsValue(Field[] fields){
        return Arrays.stream(fields)
                .filter((field) -> !Objects.equals("serialVersionUID", field.getName()))
                .map(field -> {
                    field.setAccessible(true);
                    Object o = null ;
                    try{
                        o = field.get(this);
                    }catch (Exception e){
                        o = "" ;
                    }
                    return String.format("%s:%s",field.getName(),o ) ;
                })
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
        Books books = new Books();
        String[] columns = books.columns();
        System.out.println(Arrays.toString(columns));
    }


}
